package com.ruoyi.sensitiveword;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

// 核心DFA过滤器类
public class SensitiveWordFilter {
    private final TrieNode root = new TrieNode();

    /**
     * 从集合初始化敏感词库，构建DFA树
     *
     * @param sensitiveWords 敏感词集合
     */
    public void init(Set<String> sensitiveWords) {
        for (String word : sensitiveWords) {
            addWord(word.trim());
        }
    }

    /**
     * 添加单个敏感词到DFA树
     *
     * @param word 敏感词
     */
    private void addWord(String word) {
        if (word == null || word.isEmpty()) return;

        TrieNode currentNode = root;
        for (char c : word.toCharArray()) {
            currentNode.addChild(c);
            currentNode = currentNode.getChild(c);
        }
        currentNode.setEnd(true); // 标记从根节点到当前节点的路径构成一个完整的敏感词
    }

    /**
     * 检查文本是否包含任何敏感词
     *
     * @param text 待检查文本
     * @return true表示包含敏感词
     */
    public boolean containsSensitiveWord(String text) {
        if (text == null || text.isEmpty()) return false;

        for (int i = 0; i < text.length(); i++) {
            TrieNode node = root;
            for (int j = i; j < text.length(); j++) {
                node = node.getChild(text.charAt(j));
                if (node == null) break; // 当前路径不匹配，跳出内层循环，从下一个字符开始
                if (node.isEnd()) {
                    return true; // 发现敏感词
                }
            }
        }
        return false;
    }

    /**
     * 获取文本中所有匹配到的敏感词
     *
     * @param text 待检查文本
     * @return 敏感词集合
     */
    public Set<String> getSensitiveWords(String text) {
        Set<String> foundWords = new HashSet<>();
        if (text == null || text.isEmpty()) return foundWords;

        for (int i = 0; i < text.length(); i++) {
            TrieNode node = root;
            StringBuilder wordBuffer = new StringBuilder();
            for (int j = i; j < text.length(); j++) {
                char currentChar = text.charAt(j);
                node = node.getChild(currentChar);
                if (node == null) break;

                wordBuffer.append(currentChar);
                if (node.isEnd()) {
                    foundWords.add(wordBuffer.toString()); // 记录找到的敏感词
                    // 这里不break，以便找出所有匹配（包括包含关系的长词，如"敏感"和"敏感词"）
                }
            }
        }
        return foundWords;
    }

    /**
     * 将敏感词替换为指定字符（例如***）
     *
     * @param text            原始文本
     * @param replacementChar 替换字符，如'*'
     * @return 过滤后的文本
     */
    public String replaceSensitiveWords(String text, char replacementChar) {
        if (text == null || text.isEmpty()) return text;

        char[] resultChars = text.toCharArray();
        for (int i = 0; i < resultChars.length; i++) {
            TrieNode node = root;
            int matchLength = 0;
            // 检查从位置i开始的最长敏感词匹配
            for (int j = i; j < resultChars.length; j++) {
                node = node.getChild(resultChars[j]);
                if (node == null) break;
                if (node.isEnd()) {
                    matchLength = j - i + 1; // 记录匹配到的敏感词长度
                }
            }
            // 如果找到匹配，则将这部分字符替换
            if (matchLength > 0) {
                Arrays.fill(resultChars, i, i + matchLength, replacementChar);
                i += matchLength - 1; // 跳过已替换的部分
            }
        }
        return new String(resultChars);
    }

    // 测试示例
    public static void main(String[] args) {
        // 从文件读取敏感词
        Set<String> wordSet = new HashSet<>();
        try {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                            SensitiveWordFilter.class.getClassLoader()
                                    .getResourceAsStream("sensiticeWord.txt"),
                            StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.trim().isEmpty()) {
                    wordSet.add(line.trim());
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


        SensitiveWordFilter filter = new SensitiveWordFilter();
        filter.init(wordSet);

        String testText = "这是一条包含敏感词和违规内容的文本，需要过滤。傻子，日了";
        System.out.println("是否包含敏感词: " + filter.containsSensitiveWord(testText));
        System.out.println("找到的敏感词: " + filter.getSensitiveWords(testText));
        System.out.println("过滤后文本: " + filter.replaceSensitiveWords(testText, '*'));
    }

}
